package com.wyp.design.pattern.creational.prototype.v3;

import java.io.*;
import java.util.Date;

/**
 * 引用类型克隆
 *
 * @author: Oliver
 * @time: 2020/5/8/22:37
 */
public class Pet implements Cloneable, Serializable {
    private static final long serialVersionUID = 1L;
    private String name;
    private Date birthday;


    public Pet(String name, Date birthday) {
        this.name = name;
        this.birthday = birthday;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }

    /**
     * 创建一个新对象，新对象的属性和原来对象完全相同，对于非基本类型属性，仍指向原有属性所指向的对象的内存地址  浅拷贝
     * ，属性中引用的其他对象也会被克隆，不再指向原有对象地址  深拷贝
     * 方法一 既对象的引用类型属性和属性的应用类型属性都实现Cloneable，重写clone方法并在clone方法中进行调用。Date已经实现了Cloneable
     * 方法二：字节流方式，反序列化和序列化操作
     *
     * @return
     * @throws CloneNotSupportedException
     */
    @Override
    protected Object clone() throws CloneNotSupportedException {
//        Pet pig = (Pet) super.clone();
//        pig.birthday = (Date) pig.birthday.clone();
//        return pig;

        /**
         * 报错java.io.EOFException ,因为baos刚刚建立就是用了  ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
         *
         */
        try {
            ByteArrayOutputStream baos = new ByteArrayOutputStream();
            ObjectOutputStream oos = new ObjectOutputStream(baos);
            oos.writeObject(this);
            oos.flush();
            ByteArrayInputStream bais = new ByteArrayInputStream(baos.toByteArray());
            ObjectInputStream ois = new ObjectInputStream(bais);
            Object o = ois.readObject();
            return o;
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    @Override
    public String toString() {
        return "Pet{" +
                "name='" + name + '\'' +
                ", birthday=" + birthday +
                '}' + super.toString();
    }
}
